#include "pipeline.h"

#include <iostream>
#include <utility>

using namespace cfg;

// 模板 Provider：template_provider
// 作用：读取选项中的 path 与 value，将字符串写入到构建器对应路径。
// 约定：
//   - 必填选项：path, value。
//   - 若缺失必填选项，应当写入 out_errors 并返回 false，以便 Runner 聚合并中断后续阶段。
class TemplateProviderEcho : public IProvider
{
public:
    // 作用：按选项写入键值对到 builder。
    // 参数：
    //   - builder: 可变构建器。
    //   - options: 插件选项（string→string）。必含 path、value。
    //   - out_errors: 错误输出集合。
    // 返回：
    //   - true 表示成功；
    //   - false 表示致命配置错误（例如缺失必填选项）。
    bool provide(Builder & builder,
                 const PluginOptions & options,
                 std::vector<ConfigError> & out_errors) override
    {
        auto it_path = options.find("path");
        auto it_val = options.find("value");
        if (it_path == options.end())
        {
            out_errors.push_back(ConfigError{
                Errc::Other, "template_provider: missing required option 'path'", {"path"}});
            return false;
        }
        if (it_val == options.end())
        {
            out_errors.push_back(ConfigError{
                Errc::Other, "template_provider: missing required option 'value'", {"value"}});
            return false;
        }
        const std::string & p = it_path->second;
        const std::string & v = it_val->second;
        if (!p.empty() && p.front() == '/')
            builder.set_pointer(p, v);
        else
            builder.set(p, v);
        return true;
    }
};

// 模板 Transformer：template_transformer
// 作用：将一个固定的标记写入到指定路径；缺失选项视为非致命，写入警告并继续。
// 约定：
//   - 可选选项：path（默认 "template.transformed"）、value（默认 "yes"）。
//   - 遇到非法配置（如空路径）时，写入 out_errors 警告，但返回 true（不中断流水线）。
class TemplateTransformerMark : public ITransformer
{
public:
    // 作用：在构建器上写入标记值（非致命）。
    // 返回：始终返回 true，遇到问题通过 out_errors 写入告警性诊断。
    bool transform(Builder & builder,
                   const PluginOptions & options,
                   std::vector<ConfigError> & out_errors) override
    {
        std::string path = "template.transformed";
        std::string value = "yes";
        if (auto it = options.find("path"); it != options.end())
            path = it->second;
        if (auto it = options.find("value"); it != options.end())
            value = it->second;
        if (path.empty())
        {
            out_errors.push_back(ConfigError{
                Errc::Other, "template_transformer: empty path, skip writing", {"path"}});
            return true; // 非致命：不中断
        }
        if (path.front() == '/')
            builder.set_pointer(path, value);
        else
            builder.set(path, value);
        return true;
    }
};

// 模板 Validator：template_validator
// 作用：校验给定路径存在且为字符串；缺失或类型不符时给出结构化错误。
// 选项：
//   - path（必填）：校验路径。
class TemplateValidatorRequireString : public IValidator
{
public:
    // 作用：校验路径存在且类型为字符串，错误将追加到 out_errors。
    void validate(const View & view,
                  const PluginOptions & options,
                  std::vector<ConfigError> & out_errors) override
    {
        auto it = options.find("path");
        if (it == options.end())
            return; // 无配置则忽略
        const std::string & p = it->second;
        auto maybe = view.lookup(p);
        if (!maybe)
        {
            out_errors.push_back(
                ConfigError{Errc::MissingKey, std::string("missing required key: ") + p, {p}});
            return;
        }
        auto s = maybe->get_string();
        if (!s.has_value())
        {
            ConfigError e{
                Errc::StringExpectedForPattern, std::string("string expected at ") + p, {p}};
            e.expected_type = SchemaValueType::String;
            e.actual_type = maybe->value_type();
            out_errors.push_back(std::move(e));
        }
    }
};

// 注册模板插件（可直接复制改名使用）
REGISTER_PROVIDER("template_provider", TemplateProviderEcho);
REGISTER_TRANSFORMER("template_transformer", TemplateTransformerMark);
REGISTER_VALIDATOR("template_validator", TemplateValidatorRequireString);

// 示例 main：展示如何通过 PipelineRunner 直接组装并运行（可对照 ConfigWeave 外观）。
int
main()
{
    // 组装流水线规范
    PipelineSpec spec;
    spec.providers.push_back(ProviderSpec{
        "template_provider", PluginOptions{{"path", "template.hello"}, {"value", "world"}}});
    spec.transformers.push_back(TransformerSpec{
        "template_transformer", PluginOptions{{"path", "/template/mark"}, {"value", "ok"}}});
    spec.validators.push_back(
        ValidatorSpec{"template_validator", PluginOptions{{"path", "/template/hello"}}});

    // 运行流水线
    PipelineRunner runner;
    PipelineResult result = runner.run(spec);

    std::cout << "template pipeline result: " << (result.root ? "ok" : "no-root") << "\n";

    // 读取并打印关键值
    View v(result.root);
    if (auto hello = v.lookup("/template/hello"))
    {
        if (auto s = hello->get_string())
            std::cout << "template.hello = " << *s << "\n";
    }
    if (auto mark = v.lookup("/template/mark"))
    {
        if (auto s = mark->get_string())
            std::cout << "template.mark = " << *s << "\n";
    }

    // 打印错误（若有）
    if (!result.errors.empty())
    {
        std::cout << "errors (" << result.errors.size() << "):\n";
        for (const auto & e : result.errors)
        {
            std::cout << " - code=" << static_cast<int>(e.code) << ", msg=" << e.message << "\n";
        }
    }
    return 0;
}
